home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / PowerMacOberon 1.2 / Source / Tools / Backup.Mod (.txt) next >
Oberon Text  |  1995-08-22  |  11KB  |  289 lines

  1. Syntax10.Scn.Fnt
  2. FoldElems
  3. Syntax10.Scn.Fnt
  4. (* ----------------------------------------------------------
  5. Backup does an incremental backup between two directories, i.e. only the files that
  6. have changed since the last backup are copied.
  7.     Backup.WriteFiles ( {source destination} ~ | "^")
  8. Source and destination are given as Macintosh path names starting with the volume name
  9. and ending with ":". If a path name contains blanks it must be written under quotes.
  10. Example:
  11.     Backup.WriteFiles    Othello:Text:Lectures:EiP:    hm:Backup:EiP: ~
  12. ----------------------------------------------------------*)
  13. Syntax10i.Scn.Fnt
  14. StampElems
  15. Alloc
  16. 8 May 95
  17. Syntax10.Scn.Fnt
  18.     VAR i: INTEGER;
  19. BEGIN
  20.     i := 0; WHILE in[i] # 0X DO out[i+1] := in[i]; INC(i) END;
  21.     out[0] := CHR(i)
  22. END MakeStr255;
  23. Syntax10.Scn.Fnt
  24.     VAR res: INTEGER;
  25. BEGIN
  26.     NEW(par);
  27.     par.ioCompletion := 0; par.ioNamePtr := SYSTEM.ADR(spec.name);
  28.     par.ioVRefNum := spec.vRefNum; par.ioDirID := spec.parID; par.ioFDirIndex := 0;
  29.     res := PBGetCatInfo(par); ASSERT(res = 0)
  30. END GetFileInfo;
  31. Syntax10.Scn.Fnt
  32.     VAR res: INTEGER;
  33. BEGIN
  34.     NEW(par);
  35.     par.ioCompletion := 0; par.ioNamePtr := SYSTEM.ADR(spec.name);
  36.     par.ioVRefNum := spec.vRefNum; par.ioDrDirID := spec.parID; par.ioFDirIndex := 0;
  37.     res := PBGetCatInfo(par); ASSERT(res = 0)
  38. END GetDirInfo;
  39. Syntax10.Scn.Fnt
  40.     VAR ch, start: CHAR; i: INTEGER;
  41. BEGIN
  42.     REPEAT In.Char(ch) UNTIL (ch > " ") OR ~In.Done;
  43.     i := 1;
  44.     IF (ch = '"') OR (ch = "'") THEN
  45.         start := ch; In.Char(ch);
  46.         WHILE In.Done & (ch # start) DO s[i] := ch; INC(i); In.Char(ch) END;
  47.         In.Char(ch);
  48.     ELSE
  49.         WHILE In.Done & (ch > " ") DO s[i] := ch; INC(i); In.Char(ch) END
  50.     END;
  51.     s[i] := 0X; s[0] := CHR(i-1)
  52. END ReadString;
  53. Syntax10.Scn.Fnt
  54.     VAR i: INTEGER;
  55. BEGIN
  56.     FOR i := 1 TO ORD(s[0]) DO Out.Char(s[i]) END
  57. END PrintString;
  58. Syntax10.Scn.Fnt
  59.     VAR i: INTEGER;
  60. BEGIN
  61.     IF a[0] # b[0] THEN RETURN FALSE END;
  62.     i := ORD(a[0]); WHILE (i > 0) & (a[i] = b[i]) DO DEC(i) END;
  63.     RETURN i = 0
  64. END EqualString;
  65. Syntax10.Scn.Fnt
  66.     VAR f: File;
  67. BEGIN
  68.     NEW(f); f.next := NIL; f.spec := spec;
  69.     f.date := info.ioFlMdDat; f.len := info.ioFlLgLen; f.rlen := info.ioFlRLgLen;
  70.     f.creator := info.ioFlFndrInfo.fdCreator; f.type := info.ioFlFndrInfo.fdType;
  71.     IF f.len > maxLen THEN maxLen := f.len END;
  72.     IF f.rlen > maxLen THEN maxLen := f.rlen END;
  73.     RETURN f
  74. END NewFile;
  75. Syntax10.Scn.Fnt
  76.     VAR g: File;
  77. BEGIN
  78.     g := d.files;
  79.     WHILE (g # NIL) & ~EqualString(f.spec.name, g.spec.name) DO g := g.next END;
  80.     RETURN g
  81. END ThisFile;
  82. Syntax10.Scn.Fnt
  83. FoldElems
  84. Syntax10.Scn.Fnt
  85. IF g # NIL THEN
  86.         res := Sys.FSpDelete(g.spec); ASSERT(res = 0, 99)
  87.     ELSE
  88.         NEW(g);
  89.         FOR i := 0 TO ORD(f.spec.name[0]) DO s[i] := f.spec.name[i] END;
  90.         res := Sys.FSMakeFSSpec(dt.spec.vRefNum, dt.dirID, s, g.spec); ASSERT(res = fnfErr, 98)
  91.     END;
  92.     res := Sys.FSpCreate(g.spec, f.creator, f.type, Sys.smSystemScript); ASSERT(res = 0, 97);
  93. Syntax10i.Scn.Fnt
  94. Syntax10.Scn.Fnt
  95. res := Sys.FSpOpenDF(f.spec, 0, fRef); ASSERT(res = 0, 96);
  96.     res := Sys.FSpOpenDF(g.spec, 0, gRef); ASSERT(res = 0, 95);
  97.     res := Sys.FSRead(fRef, f.len, SYSTEM.ADR(buf^)); ASSERT(res = 0, 94);
  98.     res := Sys.FSWrite(gRef, f.len, SYSTEM.ADR(buf^)); ASSERT(res = 0, 93);
  99.     res := Sys.FSClose(fRef); ASSERT(res = 0, 92);
  100.     res := Sys.FSClose(gRef); ASSERT(res = 0, 91);
  101.     PrintString(f.spec.name);
  102. Syntax10.Scn.Fnt
  103. IF f.rlen > 0 THEN
  104.         res := Sys.FSpOpenRF(f.spec, 0, fRef); ASSERT(res = 0, 90);
  105.         res := Sys.FSpOpenRF(g.spec, 0, gRef); ASSERT(res = 0, 89);
  106.         res := Sys.FSRead(fRef, f.rlen, SYSTEM.ADR(buf^)); ASSERT(res = 0, 88);
  107.         res := Sys.FSWrite(gRef, f.rlen, SYSTEM.ADR(buf^)); ASSERT((res = 0) OR (res = -5000), 87);
  108.         IF res = -5000 THEN
  109.             Out.String(" (error -5000)")
  110.         END;
  111.         res := Sys.FSClose(fRef); ASSERT(res = 0, 86);
  112.         res := Sys.FSClose(gRef); ASSERT(res = 0, 85);
  113.         Out.String(" + resources")
  114.     END;
  115.     VAR res, i: INTEGER; s: Sys.Str255; fRef, gRef: INTEGER; info: FileInfo;
  116. BEGIN
  117. create empty g on dt
  118. copy data fork
  119. copy resource fork
  120.     Out.String(" saved$"); INC(savedFiles)
  121. END SaveFile;
  122. Syntax10.Scn.Fnt
  123.     VAR d: Directory; info: DirInfo; res: INTEGER;
  124. BEGIN
  125.     NEW(d); d.next := NIL; d.files := NIL; d.dirs := NIL;
  126.     d.spec := spec;
  127.     GetDirInfo(spec, info); d.dirID := info.ioDrDirID; d.date := info.ioDrMdDat;
  128.     RETURN d
  129. END NewDir;
  130. Syntax10.Scn.Fnt
  131.     VAR spec: Sys.FSSpec; s: Sys.Str255; res, i: INTEGER; dummy: LONGINT;
  132. BEGIN
  133.     FOR i := 0 TO ORD(df.spec.name[0]) DO s[i] := df.spec.name[i] END;
  134.     res := Sys.FSMakeFSSpec(parent.spec.vRefNum, parent.dirID, s, spec); ASSERT(res = fnfErr, 29);
  135.     res := Sys.FSpDirCreate(spec, Sys.smSystemScript, dummy); ASSERT(res = 0, 30);
  136.     dt := NewDir(spec)
  137. END CreateDir;
  138. Syntax10.Scn.Fnt
  139.     VAR g: File;
  140. BEGIN
  141.     g := d.dirs;
  142.     WHILE (g # NIL) & ~EqualString(f.spec.name, g.spec.name) DO g := g.next END;
  143.     RETURN g
  144. END ThisDir;
  145. Syntax10.Scn.Fnt
  146.     VAR f: File; i: INTEGER;
  147. BEGIN
  148.     FOR i := 1 TO indent DO Out.String("  ") END;
  149.     Out.String("--- "); PrintString(d.spec.name); Out.Ln;
  150.     f := d.files;
  151.     WHILE f # NIL DO
  152.         FOR i := 1 TO indent DO Out.String("  ") END;
  153.         Out.String("   "); PrintString(f.spec.name); Out.Ln;
  154.         f := f.next
  155.     END;
  156.     f := d.dirs;
  157.     WHILE f # NIL DO PrintDir(f(Directory), indent + 1); f := f.next END
  158. END PrintDir;
  159. Syntax10.Scn.Fnt
  160.     VAR f: File; d1: Directory; par: FileInfo; res, n, i: INTEGER; spec: Sys.FSSpec; s: Sys.Str255;
  161. BEGIN
  162.     n := 1; Out.Char(".");
  163.     NEW(par); par.ioCompletion := 0; par.ioVRefNum := d.spec.vRefNum;
  164.     LOOP
  165.         s[0] := 0X; par.ioNamePtr := SYSTEM.ADR(s);
  166.         par.ioDirID := d.dirID;
  167.         par.ioFDirIndex := n; INC(n);
  168.         res := Sys.PBGetCatInfo(par);
  169.         IF res = 0 THEN
  170.             res := Sys.FSMakeFSSpec(d.spec.vRefNum, d.dirID, s, spec); ASSERT(res = 0);
  171.             IF ODD(par.ioFlAttrib DIV 16) THEN (*directory*)
  172.                 d1 := NewDir(spec); d1.next := d.dirs; d.dirs := d1
  173.             ELSE (*file*)
  174.                 f := NewFile(spec, par); f.next := d.files; d.files := f
  175.             END
  176.         ELSIF res = fnfErr THEN EXIT
  177.         ELSE HALT(20)
  178.         END
  179.     END;
  180.     f := d.dirs;
  181.     WHILE f # NIL DO FillDir(f(Directory)); f := f.next END
  182. END FillDir;
  183. Syntax10.Scn.Fnt
  184.     VAR f, g: File; first: BOOLEAN;
  185. BEGIN
  186.     f := df.files; first := TRUE;
  187.     WHILE f # NIL DO
  188.         g := ThisFile(dt, f);
  189.         IF (g = NIL) OR (f.date > g.date) THEN
  190.             IF first THEN Out.String("-- "); PrintString(df.spec.name); Out.Ln; first := FALSE END;
  191.             SaveFile(f, g, dt)
  192.         END;
  193.         f := f.next
  194.     END;
  195.     f := df.dirs;
  196.     WHILE f # NIL DO
  197.         g := ThisDir(dt, f);
  198.         IF g = NIL THEN CreateDir(f(Directory), dt, g) END;
  199.         SaveDir(f(Directory), g(Directory));
  200.         f := f.next
  201. END SaveDir;
  202. Syntax10b.Scn.Fnt
  203. Syntax10.Scn.Fnt
  204.     VAR path: Sys.Str255; df, dt: Directory; res: INTEGER; spec: Sys.FSSpec;
  205. BEGIN
  206.     In.Open; Out.Open; savedFiles := 0;
  207.     LOOP
  208.         ReadString(path);
  209.         IF (path[0] = 0X) OR (path[1] = "~") THEN EXIT END;
  210.         res := Sys.FSMakeFSSpec(0, 0, path, spec);
  211.         IF res # 0 THEN Out.F("-- Invalid source directory. res = #$", res); EXIT END;
  212.         df := NewDir(spec);
  213.         ReadString(path);
  214.         res := Sys.FSMakeFSSpec(0, 0, path, spec);
  215.         IF res # 0 THEN Out.F("-- Invalid destination directory. res = #$", res); EXIT END;
  216.         dt := NewDir(spec);
  217.         maxLen := 0;
  218.         Out.String("Reading directories");
  219.         FillDir(df); FillDir(dt);
  220.         Out.Ln;
  221.         NEW(buf, maxLen);
  222.         (*PrintDir(df, 0); PrintDir(dt, 0);*)
  223.         SaveDir(df, dt)
  224.     END;
  225.     Out.F("$# files saved$", savedFiles);
  226.     Out.Close; buf := NIL
  227. END WriteFiles;
  228. Documentation
  229. MODULE Backup;    (* HM 
  230. IMPORT Sys, In, Out, SYSTEM;
  231. CONST
  232.     fnfErr = -43;
  233.     File = POINTER TO FileDesc;
  234.     FileDesc = RECORD
  235.         next: File;
  236.         spec: Sys.FSSpec;
  237.         date, len, rlen, creator, type: LONGINT
  238.     END;
  239.     Directory = POINTER TO DirectoryDesc;
  240.     DirectoryDesc = RECORD (FileDesc)
  241.         dirID: LONGINT;
  242.         files: File;    (*the files in this directory*)
  243.         dirs: File    (*the subdirectories in this directory*)
  244.     END;
  245.     DirInfo = POINTER TO DirInfoDesc;
  246.     DirInfoDesc = RECORD (Sys.CInfoPBRec)
  247.         ioDrUsrWds: Sys.DInfo;
  248.         ioDrDirID: LONGINT;
  249.         ioDrNmFls: INTEGER;
  250.         f3: ARRAY 9 OF INTEGER;
  251.         ioDrCrDat: LONGINT;
  252.         ioDrMdDat: LONGINT;
  253.         ioDrBkDat: LONGINT;
  254.         ioDrFndrInfo: Sys.DXInfo;
  255.         ioDrParID: LONGINT
  256.     END;
  257.     FileInfo = Sys.CInfoPBFilePtr;
  258.     maxLen: LONGINT;    (*max. file length (determines buffer sizes)*)
  259.     buf: POINTER TO ARRAY OF CHAR;    (*files are copied via this buffer*)
  260.     savedFiles: LONGINT;    (*number of saved files*)
  261.     PBGetCatInfo: PROCEDURE (parm: Sys.ParmBlkPtr): INTEGER;
  262. (*--- toolbox*)
  263. PROCEDURE MakeStr255 (VAR in: ARRAY OF CHAR; VAR out: Sys.Str255);    
  264. PROCEDURE GetFileInfo (spec: Sys.FSSpec; VAR par: FileInfo);    
  265. PROCEDURE GetDirInfo (spec: Sys.FSSpec; VAR par: DirInfo);    
  266. (*--- auxiliaries*)
  267. PROCEDURE ReadString (VAR s: ARRAY OF CHAR);    
  268. PROCEDURE PrintString (s: ARRAY OF CHAR);    
  269. PROCEDURE EqualString (a, b: ARRAY OF CHAR): BOOLEAN;    
  270. (*--- files*)
  271. PROCEDURE NewFile (spec: Sys.FSSpec; info: FileInfo): File;    
  272. PROCEDURE ThisFile (d: Directory; f: File): File;    
  273. PROCEDURE SaveFile (f, g: File; dt: Directory);    
  274. (*--- directories*)
  275. PROCEDURE NewDir (spec: Sys.FSSpec): Directory;    
  276. PROCEDURE CreateDir (df, parent: Directory; VAR dt: File);    
  277. PROCEDURE ThisDir (d: Directory; f: File): File;    
  278. PROCEDURE PrintDir (d: Directory; indent: INTEGER);    
  279. PROCEDURE FillDir (d: Directory);    
  280. PROCEDURE SaveDir (df, dt: Directory);    
  281. PROCEDURE WriteFiles*;    
  282. BEGIN
  283.     Sys.Assign("PBGetCatInfoSync", SYSTEM.ADR(PBGetCatInfo));
  284. END Backup.
  285. Backup.WriteFiles Othello:Text:Vorlesungen:PI2:    hm:Backup:PI2: ~
  286. Backup.WriteFiles "Othello:Text:Vorlesungen:EiP:"    hm:Backup:EiP: ~
  287. Backup.WriteFiles Othello:AA:    hm:Backup: ~
  288. System.Free Backup~
  289.